<template><div><h2 id="yii-框架-2-0-的升级说明" tabindex="-1"><a class="header-anchor" href="#yii-框架-2-0-的升级说明"><span>Yii 框架 2.0 的升级说明</span></a></h2>
<p>此文件是针对 Yii 2.0 的升级说明，这些说明强调了当您将 Yii 从一个版本升级到另一个版本时可能会破坏应用程序的更改。<br>
即使，我们尽可能地确保向后兼容性（BC），有时想要避免这些问题会变得不可能或非常复杂，但我们同时，仍然为问题创建一个好的解决方案。您可能还想查看 <a href="https://learnku.com/docs/yii-framework/2.0.x/version-description/11974" target="_blank" rel="noopener noreferrer">版本控制策略</a> 以了解更多细节。</p>
<p>升级通常和在 composer.json 中更新依赖项一样简单，然后运行 <code v-pre>composer update</code> 。然而，在一个大的应用程序中，可能有更多的事情需要考虑，这在下面解释：</p>
<blockquote>
<p>Note: 本文档假设您已经 <a href="http://www.yiiframework.com/doc-2.0/guide-start-installation.html#installing-composer" target="_blank" rel="noopener noreferrer">全局安装了 composer</a>，以便可以运行 <code v-pre>composer</code> 命令。在项目中，如果你有 <code v-pre>composer.phar</code> 文件，将 <code v-pre>composer</code> 替换为 <code v-pre>php composer.phar</code>，以下文中都要这样。</p>
</blockquote>
<blockquote>
<p>Tip: 升级复杂软件项目的依赖关系总是会带来破坏某些东西的风险，所以请确保有备份（反正你也该这么做 😉 ）。</p>
</blockquote>
<p>假如，你使用 <a href="https://github.com/fxpio/composer-asset-plugin" target="_blank" rel="noopener noreferrer">composer asset plugin</a> 代替当前推荐的 <a href="https://asset-packagist.org/" target="_blank" rel="noopener noreferrer">asset-packagist.org</a> 去安装 Bower 和 NPM 资源包，也要确保它也被升级到最新的版本。为了确保最好的稳定性，你还应该升级 composer，按以下步骤：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> self-update</span>
<span class="line"><span class="token function">composer</span> global require <span class="token string">"fxp/composer-asset-plugin:^1.4.1"</span> --no-plugins</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>升级 Yii 的简单方法，例如，你想升级到 2.0.10 版本，可以运行 <code v-pre>composer require</code> 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> require <span class="token string">"yiisoft/yii2:~2.0.10"</span> --update-with-dependencies</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果需要，这个命令只会升级 Yii 和它的直接依赖项。当您选择的 Yii 版本与您之前的版本有轻微不同的依赖关系时，如果不带上 <code v-pre>--update-with-dependencies</code> 这个升级可能会失败。默认情况下，作为安全特性，<code v-pre>composer require</code> 不会更新任何其他包。</p>
<p>另一种升级的方法是更改 <code v-pre>composer.json</code> 文件，来要求新的 Yii 版本，然后通过指定所有允许更新的包来运行 <code v-pre>composer update</code> 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line"><span class="token function">composer</span> update yiisoft/yii2 yiisoft/yii2-composer bower-asset/inputmask</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>上面的命令将只更新指定的包，并保持所有其他依赖项的版本不变。这有助于一步一步地更新包，而不会导致大量可能以某种方式中断的包版本更改。如果你感到幸运，你当然可以通过运行没有任何限制的 <code v-pre>composer update</code> 命令，将所有内容更新到最新版本。</p>
<p>升级后，您应该检查应用程序是否仍按预期工作，并且没有测试被破坏。</p>
<p>关于从一个版本升级到另一个版本时需要考虑的更改，请参阅下面的说明。</p>
<blockquote>
<p>Note: 以下的升级说明是递增积累的。也就是说，如果您想从版本 A 升级到版本 C，并且在 A 和 C 之间存在版本 B，您需要同时遵循 A 和 B 的说明。</p>
</blockquote>
<h2 id="从-yii-2-0-45-升级" tabindex="-1"><a class="header-anchor" href="#从-yii-2-0-45-升级"><span>从 Yii 2.0.45 升级</span></a></h2>
<ul>
<li>在 2.0.45 中引入的 <code v-pre>Inflector::camel2words()</code> 的更改被恢复，所以它的工作方式和2.0.45 之前一样。如果您需要 2.0.45 行为，<a href="https://github.com/yiisoft/yii2/pull/19495/files" target="_blank" rel="noopener noreferrer">请引入您自己的方法</a>;</li>
<li><code v-pre>yii\log\FileTarget::$rotateByCopy</code> 现在已弃用，设置为 <code v-pre>false</code> 没有效果，因为文件的轮询只通过复制完成。</li>
</ul>
<h2 id="从-yii-2-0-44-升级" tabindex="-1"><a class="header-anchor" href="#从-yii-2-0-44-升级"><span>从 Yii 2.0.44 升级</span></a></h2>
<ul>
<li><code v-pre>yii\filters\PageCache::$cacheHeaders</code> 由于 <a href="https://learnku.com/docs/yii-framework/2.0.x/filters/12007#61b977" title="PageCache（页面缓存过滤器）" target="_blank" rel="noopener noreferrer">PageCache（页面缓存过滤器）</a> 不再存储它们的标准化（小写）版本，现在会获取 HTTP 报头名称大小写敏感的列表，因此，请您确保该列表已正确更新，并重新创建了页面缓存。</li>
</ul>
<h2 id="从-yii-2-0-43-升级" tabindex="-1"><a class="header-anchor" href="#从-yii-2-0-43-升级"><span>从 Yii 2.0.43 升级</span></a></h2>
<ul>
<li>
<p><code v-pre>Json::encode()</code> can now handle zero-indexed objects in same way as <code v-pre>json_encode()</code> and keep them as objects. In order to avoid breaking backwards compatibility this behavior could be enabled by a new option flag but is disabled by default.</p>
<ul>
<li>
<p>Set <code v-pre>yii/helpers/Json::$keepObjectType = true</code> anywhere in your application code</p>
</li>
<li>
<p>Or configure json response formatter to enable it for all JSON responses:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">  <span class="token string single-quoted-string">'response'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'formatters'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">      <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>yii<span class="token punctuation">\</span>web<span class="token punctuation">\</span>Response</span><span class="token operator">::</span><span class="token constant">FORMAT_JSON</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\web\JsonResponseFormatter'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'prettyPrint'</span> <span class="token operator">=></span> <span class="token constant">YII_DEBUG</span><span class="token punctuation">,</span> <span class="token comment">// use "pretty" output in debug mode</span></span>
<span class="line">        <span class="token string single-quoted-string">'keepObjectType'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// keep object type for zero-indexed objects</span></span>
<span class="line">      <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">  <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
</ul>
</li>
<li>
<p><code v-pre>yii\caching\Cache::multiSet()</code> now uses the default cache duration (<code v-pre>yii\caching\Cache::$defaultDuration</code>) when no duration is provided. A duration of 0 should be explicitly passed if items should not expire.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-42" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-42"><span>Upgrade from Yii 2.0.42</span></a></h2>
<ul>
<li>
<p><code v-pre>yii\base\ErrorHandler</code> does not expose the <code v-pre>$_SERVER</code> information implicitly anymore.</p>
</li>
<li>
<p>The methods <code v-pre>phpTypecast()</code> and <code v-pre>dbTypecast()</code> of <code v-pre>yii\db\ColumnSchema</code> will no longer convert <code v-pre>$value</code> from <code v-pre>int</code> to<br>
<code v-pre>string</code>, if database column type is <code v-pre>INTEGER UNSIGNED</code> or <code v-pre>BIGINT UNSIGNED</code>.</p>
<ul>
<li>
<p>I.e. it affects update and insert queries. For example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">db</span><span class="token operator">-></span><span class="token function">createCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'{{some_table}}'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'int_unsigned_col'</span> <span class="token operator">=></span> <span class="token number">22</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>will execute next SQL:</p>
<div class="language-sql line-numbers-mode" data-highlighter="prismjs" data-ext="sql" data-title="sql"><pre v-pre class="language-sql"><code><span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>some_table<span class="token punctuation">`</span></span> <span class="token punctuation">(</span><span class="token identifier"><span class="token punctuation">`</span>int_unsigned_col<span class="token punctuation">`</span></span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">22</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
</ul>
</li>
<li>
<p>Property <code v-pre>yii\db\ColumnSchemaBuilder::$categoryMap</code> has been removed in favor of getter/setter methods <code v-pre>getCategoryMap()</code> and <code v-pre>setCategoryMap()</code>.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-41" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-41"><span>Upgrade from Yii 2.0.41</span></a></h2>
<ul>
<li><code v-pre>NumberValidator</code> (<code v-pre>number</code>, <code v-pre>double</code>, <code v-pre>integer</code>) does not allow values with leading or terminating (non-trimmed) white spaces anymore. If your application expects non-trimmed values provided to this validator make sure to trim them first (i.e. by using <code v-pre>trim</code> / <code v-pre>filter</code> “validators”).</li>
</ul>
<h2 id="upgrade-from-yii-2-0-40" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-40"><span>Upgrade from Yii 2.0.40</span></a></h2>
<ul>
<li>The methods <code v-pre>getAuthKey()</code> and <code v-pre>validateAuthKey()</code> of <code v-pre>yii\web\IdentityInterface</code> are now also used to validate active<br>
sessions (previously these methods were only used for cookie-based login). If your identity class does not properly<br>
implement these methods yet, you should update it accordingly (an example can be found in the guide under<br>
<code v-pre>Security</code> -&gt; <code v-pre>Authentication</code>). Alternatively, you can simply return <code v-pre>null</code> in the <code v-pre>getAuthKey()</code> method to keep<br>
the old behavior (that is, no validation of active sessions). Applications that change the underlying <code v-pre>authKey</code> of<br>
an authenticated identity, should now call <code v-pre>yii\web\User::switchIdentity()</code>, <code v-pre>yii\web\User::login()</code><br>
or <code v-pre>yii\web\User::logout()</code> to recreate the active session with the new <code v-pre>authKey</code>.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-39-3" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-39-3"><span>Upgrade from Yii 2.0.39.3</span></a></h2>
<ul>
<li>Priority of processing <code v-pre>yii\base\Arrayable</code>, and <code v-pre>JsonSerializable</code> data has been reversed (<code v-pre>Arrayable</code> data is checked first now) in <code v-pre>yii\base\Model</code>, and <code v-pre>yii\rest\Serializer</code>. If your application relies on the previous priority you need to fix it manually based on the complexity of desired (de)serialization result.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-38" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-38"><span>Upgrade from Yii 2.0.38</span></a></h2>
<ul>
<li>
<p>The storage structure of the file cache has been changed when you use <code v-pre>\yii\caching\FileCache::$keyPrefix</code>.<br>
It is worth warming up the cache again if there is a logical dependency when working with the file cache.</p>
</li>
<li>
<p><code v-pre>yii\web\Session</code> now respects the ‘session.use_strict_mode’ ini directive.<br>
In case you use a custom <code v-pre>Session</code> class and have overwritten the <code v-pre>Session::openSession()</code> and/or <code v-pre>Session::writeSession()</code> functions changes might be required:</p>
<ul>
<li>
<p>When in strict mode the <code v-pre>openSession()</code> function should check if the requested session id exists<br>
(and mark it for forced regeneration if not).<br>
For example, the <code v-pre>DbSession</code> does this at the beginning of the function as follows:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getUseStrictMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$id</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getReadQuery</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">exists</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">//This session id does not exist, mark it for forced regeneration</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">_forceRegenerateId</span> <span class="token operator">=</span> <span class="token variable">$id</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"><span class="token comment">// ... normal function continues ...</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>When in strict mode the <code v-pre>writeSession()</code> function should ignore writing the session under the old id.<br>
For example, the <code v-pre>DbSession</code> does this at the beginning of the function as follows:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$this</span><span class="token operator">-></span><span class="token function">getUseStrictMode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token variable">$id</span> <span class="token operator">===</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">_forceRegenerateId</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//Ignore write when forceRegenerate is active for this id</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"><span class="token comment">// ... normal function continues ...</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Note: The sample code above is specific for the <code v-pre>yii\web\DbSession</code> class.<br>
Make sure you use the correct implementation based on your parent class,<br>
e.g. <code v-pre>yii\web\CacheSession</code>, <code v-pre>yii\redis\Session</code>, <code v-pre>yii\mongodb\Session</code>, etc.</p>
</blockquote>
</li>
</ul>
<blockquote>
<p>Note: In case your custom functions call their <code v-pre>parent</code> functions, there are probably no changes needed to your code if those parents implement the <code v-pre>useStrictMode</code> checks.</p>
</blockquote>
<blockquote>
<p>Warning: in case <code v-pre>openSession()</code> and/or <code v-pre>writeSession()</code> functions do not implement the <code v-pre>useStrictMode</code> code<br>
the session could be stored under a malicious id without warning even if <code v-pre>useStrictMode</code> is enabled.</p>
</blockquote>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-37" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-37"><span>Upgrade from Yii 2.0.37</span></a></h2>
<ul>
<li>Resolving DI references inside of arrays in dependencies was made optional and turned off by default. In order<br>
to turn it on, set <code v-pre>resolveArrays</code> of container instance to <code v-pre>true</code>.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-36" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-36"><span>Upgrade from Yii 2.0.36</span></a></h2>
<ul>
<li><code v-pre>yii\db\Exception::getCode()</code> now returns full PDO code that is SQLSTATE string. If you have relied on comparing code<br>
with an integer value, adjust your code.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-35" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-35"><span>Upgrade from Yii 2.0.35</span></a></h2>
<ul>
<li>
<p>Inline validator signature has been updated with 4th parameter <code v-pre>current</code>:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * <span class="token keyword">@param</span> <span class="token class-name"><span class="token keyword">mixed</span></span> <span class="token parameter">$current</span> the currently validated value of attribute</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$attribute</span><span class="token punctuation">,</span> <span class="token variable">$params</span><span class="token punctuation">,</span> <span class="token variable">$validator</span><span class="token punctuation">,</span> <span class="token variable">$current</span><span class="token punctuation">)</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>Behavior of inline validator used as a rule of <code v-pre>EachValidator</code> has been changed - <code v-pre>$attribute</code> now refers to original<br>
model’s attribute and not its temporary counterpart:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token variable">$array_attribute</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'first'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'second'</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">rules</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span><span class="token string single-quoted-string">'array_attribute'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'each'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'rule'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'customValidatingMethod'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">customValidatingMethod</span><span class="token punctuation">(</span><span class="token variable">$attribute</span><span class="token punctuation">,</span> <span class="token variable">$params</span><span class="token punctuation">,</span> <span class="token variable">$validator</span><span class="token punctuation">,</span> <span class="token variable">$current</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// $attribute === 'array_attribute' (as before)</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// now: $this->$attribute === ['first', 'second'] (on every iteration)</span></span>
<span class="line">    <span class="token comment">// previously:</span></span>
<span class="line">    <span class="token comment">// $this->$attribute === 'first' (on first iteration)</span></span>
<span class="line">    <span class="token comment">// $this->$attribute === 'second' (on second iteration)</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// use now $current instead</span></span>
<span class="line">    <span class="token comment">// $current === 'first' (on first iteration)</span></span>
<span class="line">    <span class="token comment">// $current === 'second' (on second iteration)</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p><code v-pre>$this</code> in an inline validator defined as closure now refers to model instance. If you need to access the object registering<br>
the validator, pass its instance through use statement:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$registrar</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$validator</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token variable">$attribute</span><span class="token punctuation">,</span> <span class="token variable">$params</span><span class="token punctuation">,</span> <span class="token variable">$validator</span><span class="token punctuation">,</span> <span class="token variable">$current</span><span class="token punctuation">)</span> <span class="token keyword">use</span> <span class="token punctuation">(</span><span class="token variable">$registrar</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>Validator closure callbacks should not be declared as static.</p>
</li>
<li>
<p>If you have any controllers that override the <code v-pre>init()</code> method, make sure they are calling <code v-pre>parent::init()</code> at<br>
the beginning, as demonstrated in the <a href="https://www.yiiframework.com/doc/guide/2.0/en/concept-components" target="_blank" rel="noopener noreferrer">component guide</a>.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-34" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-34"><span>Upgrade from Yii 2.0.34</span></a></h2>
<ul>
<li>
<p><code v-pre>ExistValidator</code> used as a rule of <code v-pre>EachValidator</code> now requires providing <code v-pre>targetClass</code> explicitely and it’s not possible to use it with <code v-pre>targetRelation</code> in<br>
that configuration.</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">rules</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span><span class="token string single-quoted-string">'attribute'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'each'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'rule'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'exist'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'targetClass'</span> <span class="token operator">=></span> <span class="token keyword static-context">static</span><span class="token operator">::</span><span class="token function">className</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'targetAttribute'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'id'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
</ul>
<h2 id="upgrade-from-yii-2-0-32" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-32"><span>Upgrade from Yii 2.0.32</span></a></h2>
<ul>
<li>
<p><code v-pre>yii\helpers\ArrayHelper::filter</code> now correctly filters data when passing a filter with more than 2 “levels”,<br>
e.g. <code v-pre>ArrayHelper::filter($myArray, ['A.B.C']</code>. Until Yii 2.0.32 all data after the 2nd level was returned,<br>
please see the following example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$myArray</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'A'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'B'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'C'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'D'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'E'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'F'</span> <span class="token operator">=></span> <span class="token number">2</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">ArrayHelper</span><span class="token operator">::</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token variable">$myArray</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'B.D.E'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Before Yii 2.0.33 this would return</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'B'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'D'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'E'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'F'</span> <span class="token operator">=></span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token comment">//Please note the unexpected inclusion of other elements</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Since Yii 2.0.33 this returns</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'B'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'D'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'E'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Note: If you are only using up to 2 “levels” (e.g. <code v-pre>ArrayHelper::filter($myArray, ['A.B']</code>), this change has no impact.</p>
</li>
<li>
<p><code v-pre>UploadedFile</code> class <code v-pre>deleteTempFile()</code> and <code v-pre>isUploadedFile()</code> methods introduced in 2.0.32 were removed.</p>
</li>
<li>
<p>Exception will be thrown if <code v-pre>UrlManager::$cache</code> configuration is incorrect (previously misconfiguration was silently<br>
ignored and <code v-pre>UrlManager</code> continue to work without cache). Make sure that <code v-pre>UrlManager::$cache</code> is correctly configured<br>
or set it to <code v-pre>null</code> to explicitly disable cache.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-31" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-31"><span>Upgrade from Yii 2.0.31</span></a></h2>
<ul>
<li><code v-pre>yii\filters\ContentNegotiator</code> now generates 406 ‘Not Acceptable’ instead of 415 ‘Unsupported Media Type’ on<br>
content-type negotiation fail.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-30" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-30"><span>Upgrade from Yii 2.0.30</span></a></h2>
<ul>
<li><code v-pre>yii\helpers\BaseInflector::slug()</code> now ensures there is no repeating $replacement string occurrences.<br>
In case you rely on Yii 2.0.16 - 2.0.30 behavior, consider replacing <code v-pre>Inflector</code> with your own implementation.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-28" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-28"><span>Upgrade from Yii 2.0.28</span></a></h2>
<ul>
<li><code v-pre>yii\helpers\Html::tag()</code> now generates boolean attributes<br>
<a href="https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attribute" target="_blank" rel="noopener noreferrer">according to HTML specification</a>.<br>
For <code v-pre>true</code> value attribute is present, for <code v-pre>false</code> value it is absent.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-20" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-20"><span>Upgrade from Yii 2.0.20</span></a></h2>
<ul>
<li>
<p><code v-pre>yii\db\Query::select()</code> and <code v-pre>addSelect()</code> now normalize the format that columns are stored in when saving them<br>
to <code v-pre>$this-&gt;select</code>, so code that works directly with that property may need to be modified.</p>
<p>For the following code:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$a</span> <span class="token operator">=</span> <span class="token variable">$query</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'*'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$b</span> <span class="token operator">=</span> <span class="token variable">$query</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id, name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>The value was stored as is i.e.</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// a</span></span>
<span class="line"><span class="token punctuation">[</span><span class="token string single-quoted-string">'*'</span><span class="token punctuation">]</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// b</span></span>
<span class="line"><span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'name'</span><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Now it is stored as</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// a</span></span>
<span class="line"><span class="token punctuation">[</span><span class="token string single-quoted-string">'*'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'*'</span><span class="token punctuation">]</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// b</span></span>
<span class="line"><span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'name'</span><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
</ul>
<h2 id="upgrade-from-yii-2-0-16" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-16"><span>Upgrade from Yii 2.0.16</span></a></h2>
<ul>
<li>In case you have extended the <code v-pre>yii\web\DbSession</code> class you should check if your<br>
custom implementation is compatible with the new <code v-pre>yii\web\DbSession::$fields</code> attribute.<br>
Especially when overriding the <code v-pre>yii\web\DbSession::writeSession($id, $data)</code> function.</li>
</ul>
<h2 id="upgrade-from-yii-2-0-15" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-15"><span>Upgrade from Yii 2.0.15</span></a></h2>
<ul>
<li>
<p>Updated dependency to <code v-pre>cebe/markdown</code> to version <code v-pre>1.2.x</code>.<br>
If you need stick with 1.1.x, you can specify that in your <code v-pre>composer.json</code> by<br>
adding the following line in the <code v-pre>require</code> section:</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"cebe/markdown"</span><span class="token operator">:</span> <span class="token string">"~1.1.0"</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
<li>
<p><code v-pre>yii\mutex\Mutex::acquire()</code> no longer returns <code v-pre>true</code> if lock is already acquired by the same component in the same process.<br>
Make sure that you’re not trying to acquire the same lock multiple times in a way that may create infinite loops, for example:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">mutex</span><span class="token operator">-></span><span class="token function">acquire</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'test'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">     <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">mutex</span><span class="token operator">-></span><span class="token function">acquire</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'test'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">         <span class="token comment">// `Yii::$app->mutex->acquire('test')` will always return `false` here, since lock is already acquired</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>Formatter methods <code v-pre>asInteger</code>, <code v-pre>asDecimal</code>, <code v-pre>asPercent</code>, and <code v-pre>asCurrency</code> are using now inner fallback methods to handle<br>
very big number values to counter inner PHP casting and floating point number presentation issues. Make sure to provide<br>
such values as string numbers.</p>
</li>
<li>
<p>Active Record relations are now being reset when corresponding key fields are changed. If you have relied on the fact<br>
that relations are never reloaded you have to adjust your code.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-14" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-14"><span>Upgrade from Yii 2.0.14</span></a></h2>
<ul>
<li>
<p>When hash format condition (array) is used in <code v-pre>yii\db\ActiveRecord::findOne()</code> and <code v-pre>findAll()</code>, the array keys (column names)<br>
are now limited to the table column names. This is to prevent SQL injection if input was not filtered properly.<br>
You should check all usages of <code v-pre>findOne()</code> and <code v-pre>findAll()</code> to ensure that input is filtered correctly.<br>
If you need to find models using different keys than the table columns, use <code v-pre>find()-&gt;where(...)</code> instead.</p>
<p>It’s not an issue in the default generated code though as ID is filtered by<br>
controller code:</p>
<p>The following code examples are <strong>not</strong> affected by this issue (examples shown for <code v-pre>findOne()</code> are valid also for <code v-pre>findAll()</code>):</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// yii\web\Controller ensures that $id is scalar</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">actionView</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$model</span> <span class="token operator">=</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token function">findOne</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// casting to (int) or (string) ensures no array can be injected (an exception will be thrown so this is not a good practise)</span></span>
<span class="line"><span class="token variable">$model</span> <span class="token operator">=</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token function">findOne</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword type-casting">int</span><span class="token punctuation">)</span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// explicitly specifying the colum to search, passing a scalar or array here will always result in finding a single record</span></span>
<span class="line"><span class="token variable">$model</span> <span class="token operator">=</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token function">findOne</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>The following code however <strong>is vulnerable</strong>, an attacker could inject an array with an arbitrary condition and even exploit SQL injection:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$model</span> <span class="token operator">=</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token function">findOne</span><span class="token punctuation">(</span><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token property">request</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>For the above example, the SQL injection part is fixed with the patches provided in this release, but an attacker may still be able to search<br>
records by different condition than a primary key search and violate your application business logic. So passing user input directly like this can cause problems and should be avoided.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-13" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-13"><span>Upgrade from Yii 2.0.13</span></a></h2>
<ul>
<li>
<p>Constants <code v-pre>IPV6_ADDRESS_LENGTH</code>, <code v-pre>IPV4_ADDRESS_LENGTH</code> were moved from <code v-pre>yii\validators\IpValidator</code> to <code v-pre>yii\helpers\IpHelper</code>.<br>
If your application relies on these constants, make sure to update your code to follow the changes.</p>
</li>
<li>
<p><code v-pre>yii\base\Security::compareString()</code> is now throwing <code v-pre>yii\base\InvalidArgumentException</code> in case non-strings are compared.</p>
</li>
<li>
<p><code v-pre>yii\db\ExpressionInterface</code> has been introduced to represent a wider range of SQL expressions. In case you check for<br>
<code v-pre>instanceof yii\db\Expression</code> in your code, you might consider changing that to checking for the interface and use the newly<br>
introduced methods to retrieve the expression content.</p>
</li>
<li>
<p>Added JSON support for PostgreSQL and MySQL as well as Arrays support for PostgreSQL in ActiveRecord layer.<br>
In case you already implemented such support yourself, please switch to Yii implementation.</p>
<ul>
<li>For MySQL JSON and PgSQL JSON &amp; JSONB columns Active Record will return decoded JSON (that can be either array or scalar) after data population<br>
and expects arrays or scalars to be assigned for further saving them into a database.</li>
<li>For PgSQL Array columns Active Record will return <code v-pre>yii\db\ArrayExpression</code> object that acts as an array<br>
(it implements <code v-pre>ArrayAccess</code>, <code v-pre>Traversable</code> and <code v-pre>Countable</code> interfaces) and expects array or <code v-pre>yii\db\ArrayExpression</code> to be<br>
assigned for further saving it into the database.</li>
</ul>
<p>In case this change makes the upgrade process to Yii 2.0.14 too hard in your project, you can <a href="https://github.com/yiisoft/yii2/issues/15716#issuecomment-368143206" target="_blank" rel="noopener noreferrer">switch off the described behavior</a><br>
Then you can take your time to change your code and then re-enable arrays or JSON support.</p>
</li>
<li>
<p><code v-pre>yii\db\PdoValue</code> class has been introduced to replace a special syntax that was used to declare PDO parameter type<br>
when binding parameters to an SQL command, for example: <code v-pre>['value', \PDO::PARAM_STR]</code>.<br>
You should use <code v-pre>new PdoValue('value', \PDO::PARAM_STR)</code> instead. Old syntax will be removed in Yii 2.1.</p>
</li>
<li>
<p><code v-pre>yii\db\QueryBuilder::conditionBuilders</code> property and method-based condition builders are no longer used.<br>
Class-based conditions and builders are introduced instead to provide more flexibility, extensibility and<br>
space to customization. In case you rely on that property or override any of default condition builders, follow the<br>
special <a href="http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html#adding-custom-conditions-and-expressions" target="_blank" rel="noopener noreferrer">guide article</a><br>
to update your code.</p>
</li>
<li>
<p>Protected method <code v-pre>yii\db\ActiveQueryTrait::createModels()</code> does not apply indexes as defined in <code v-pre>indexBy</code> property anymore.<br>
In case you override default ActiveQuery implementation and relied on that behavior, call <code v-pre>yii\db\Query::populate()</code><br>
method instead to index query results according to the <code v-pre>indexBy</code> parameter.</p>
</li>
<li>
<p>Log targets (like <code v-pre>yii\log\EmailTarget</code>) are now throwing <code v-pre>yii\log\LogRuntimeException</code> in case log can not be properly exported.</p>
</li>
<li>
<p>You can start preparing your application for Yii 2.1 by doing the following:</p>
<ul>
<li>Replace <code v-pre>::className()</code> calls with <code v-pre>::class</code> (if you’re running PHP 5.5+).</li>
<li>Replace usages of <code v-pre>yii\base\InvalidParamException</code> with <code v-pre>yii\base\InvalidArgumentException</code>.</li>
<li>Replace calls to <code v-pre>Yii::trace()</code> with <code v-pre>Yii::debug()</code>.</li>
<li>Remove calls to <code v-pre>yii\BaseYii::powered()</code>.</li>
<li>If you are using XCache or Zend data cache, those are going away in 2.1 so you might want to start looking for an alternative.</li>
</ul>
</li>
<li>
<p>In case you aren’t using CSRF cookies (REST APIs etc.) you should turn them off explicitly by setting<br>
<code v-pre>\yii\web\Request::$enableCsrfCookie</code> to <code v-pre>false</code> in your config file.</p>
</li>
<li>
<p>Previously headers sent after content output was started were silently ignored. This behavior was changed to throwing<br>
<code v-pre>\yii\web\HeadersAlreadySentException</code>.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-12" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-12"><span>Upgrade from Yii 2.0.12</span></a></h2>
<ul>
<li>
<p>The <code v-pre>yii\web\Request</code> class allowed to determine the value of <code v-pre>getIsSecureConnection()</code> form the<br>
<code v-pre>X-Forwarded-Proto</code> header if the connection was made via a normal HTTP request. This behavior<br>
was insecure as the header could have been set by a malicious client on a non-HTTPS connection.<br>
With 2.0.13 Yii adds support for configuring trusted proxies. If your application runs behind a reverse proxy and relies on<br>
<code v-pre>getIsSecureConnection()</code> to return the value form the <code v-pre>X-Forwarded-Proto</code> header you need to explicitly allow<br>
this in the Request configuration. See the <a href="http://www.yiiframework.com/doc-2.0/guide-runtime-requests.html#trusted-proxies" target="_blank" rel="noopener noreferrer">guide</a> for more information.</p>
<p>This setting also affects you when Yii is running on IIS webserver, which sets the <code v-pre>X-Rewrite-Url</code> header.<br>
This header is now filtered by default and must be listed in trusted hosts to be detected by Yii:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span>   <span class="token comment">// accept X-Rewrite-Url from all hosts, as it will be set by IIS</span></span>
<span class="line">    <span class="token string single-quoted-string">'/.*/'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'X-Rewrite-Url'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>For compatibiliy with <a href="https://wiki.php.net/rfc/object-typehint" target="_blank" rel="noopener noreferrer">PHP 7.2 which does not allow classes to be named <code v-pre>Object</code> anymore</a>,<br>
we needed to rename <code v-pre>yii\base\Object</code> to <code v-pre>yii\base\BaseObject</code>.</p>
<p><code v-pre>yii\base\Object</code> still exists for backwards compatibility and will be loaded if needed in projects that are<br>
running on PHP &lt;7.2. The compatibility class <code v-pre>yii\base\Object</code> extends from <code v-pre>yii\base\BaseObject</code> so if you<br>
have classes that extend from <code v-pre>yii\base\Object</code> these would still work.</p>
<p>What does not work however will be code that relies on <code v-pre>instanceof</code> checks or <code v-pre>is_subclass_of()</code> calls<br>
for <code v-pre>yii\base\Object</code> on framework classes as these do not extend <code v-pre>yii\base\Object</code> anymore but only<br>
extend from <code v-pre>yii\base\BaseObject</code>. In general such a check is not needed as there is a <code v-pre>yii\base\Configurable</code><br>
interface you should check against instead.</p>
<p>Here is a visualisation of the change (<code v-pre>a &lt; b</code> means “b extends a”):</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">Before<span class="token punctuation">:</span></span>
<span class="line"></span>
<span class="line">yii\base\<span class="token keyword type-declaration">Object</span> <span class="token operator">&lt;</span> Framework Classes</span>
<span class="line">yii\base\<span class="token keyword type-declaration">Object</span> <span class="token operator">&lt;</span> Application Classes</span>
<span class="line"></span>
<span class="line">After Upgrade<span class="token punctuation">:</span></span>
<span class="line"></span>
<span class="line">yii\base\BaseObject <span class="token operator">&lt;</span> Framework Classes</span>
<span class="line">yii\base\BaseObject <span class="token operator">&lt;</span> yii\base\<span class="token keyword type-declaration">Object</span> <span class="token operator">&lt;</span> Application Classes</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>If you want to upgrade PHP to version 7.2 in your project you need to remove all cases that extend <code v-pre>yii\base\Object</code><br>
and extend from <code v-pre>yii\base\BaseObject</code> instead:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">yii\base\BaseObject <span class="token operator">&lt;</span> Framework Classes</span>
<span class="line">yii\base\BaseObject <span class="token operator">&lt;</span> Application Classes</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>For extensions that have classes extending from <code v-pre>yii\base\Object</code>, to be compatible with PHP 7.2, you need to<br>
require <code v-pre>&quot;yiisoft/yii2&quot;: &quot;~2.0.13&quot;</code> in composer.json and change affected classes to extend from <code v-pre>yii\base\BaseObject</code><br>
instead. It is not possible to allow Yii versions <code v-pre>&lt;2.0.13</code> and be compatible with PHP 7.2 or higher.</p>
</li>
<li>
<p>A new method <code v-pre>public static function instance($refresh = false);</code> has been added to the <code v-pre>yii\db\ActiveRecordInterface</code> via a new<br>
<code v-pre>yii\base\StaticInstanceInterface</code>. This change may affect your application in the following ways:</p>
<ul>
<li>If you have an <code v-pre>instance()</code> method defined in an <code v-pre>ActiveRecord</code> or <code v-pre>Model</code> class, you need to check whether the behavior is<br>
compatible with the method added by Yii.</li>
<li>Otherwise this method is implemented in the <code v-pre>yii\base\Model</code>, so the change only affects your code if you implement <code v-pre>ActiveRecordInterface</code><br>
in a class that does not extend <code v-pre>Model</code>. You may use <code v-pre>yii\base\StaticInstanceTrait</code> to implement it.</li>
</ul>
</li>
<li>
<p>Fixed built-in validator creating when model has a method with the same name.</p>
<p>It is documented, that for the validation rules declared in model by <code v-pre>yii\base\Model::rules()</code>, validator can be either<br>
a built-in validator name, a method name of the model class, an anonymous function, or a validator class name.<br>
Before this change behavior was inconsistent with the documentation: method in the model had higher priority, than<br>
a built-in validator. In case you have relied on this behavior, make sure to fix it.</p>
</li>
<li>
<p>Behavior was changed for methods <code v-pre>yii\base\Module::get()</code> and <code v-pre>yii\base\Module::has()</code> so in case when the requested<br>
component was not found in the current module, the parent ones will be checked for this component hierarchically.<br>
Considering that the root parent module is usually an application, this change can reduce calls to global <code v-pre>Yii::$app-&gt;get()</code>,<br>
and replace them with module-scope calls to <code v-pre>get()</code>, making code more reliable and easier to test.<br>
However, this change may affect your application if you have code that uses method <code v-pre>yii\base\Module::has()</code> in order<br>
to check existence of the component exactly in this specific module. In this case make sure the logic is not corrupted.</p>
</li>
<li>
<p>If you are using “asset” command to compress assets and your web application <code v-pre>assetManager</code> has <code v-pre>linkAssets</code> turned on,<br>
make sure that “asset” command config has <code v-pre>linkAssets</code> turned on as well.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-11" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-11"><span>Upgrade from Yii 2.0.11</span></a></h2>
<ul>
<li>
<p><code v-pre>yii\i18n\Formatter::normalizeDatetimeValue()</code> returns now array with additional third boolean element<br>
indicating whether the timestamp has date information or it is just time value.</p>
</li>
<li>
<p><code v-pre>yii\grid\DataColumn</code> filter is now automatically generated as dropdown list with localized <code v-pre>Yes</code> and <code v-pre>No</code> strings<br>
in case of <code v-pre>format</code> being set to <code v-pre>boolean</code>.</p>
</li>
<li>
<p>The signature of <code v-pre>yii\db\QueryBuilder::prepareInsertSelectSubQuery()</code> was changed. The method has got an extra optional parameter<br>
<code v-pre>$params</code>.</p>
</li>
<li>
<p>The signature of <code v-pre>yii\cache\Cache::getOrSet()</code> has been adjusted to also accept a callable and not only <code v-pre>Closure</code>.<br>
If you extend this method, make sure to adjust your code.</p>
</li>
<li>
<p><code v-pre>yii\web\UrlManager</code> now checks if rules implement <code v-pre>getCreateUrlStatus()</code> method in order to decide whether to use<br>
internal cache for <code v-pre>createUrl()</code> calls. Ensure that all your custom rules implement this method in order to fully<br>
benefit from the acceleration provided by this cache.</p>
</li>
<li>
<p><code v-pre>yii\filters\AccessControl</code> now can be used without <code v-pre>user</code> component. This has two consequences:</p>
<ol>
<li>If used without user component, <code v-pre>yii\filters\AccessControl::denyAccess()</code> throws <code v-pre>yii\web\ForbiddenHttpException</code> instead of redirecting to login page.</li>
<li>If used without user component, using <code v-pre>AccessRule</code> matching a role throws <code v-pre>yii\base\InvalidConfigException</code>.</li>
</ol>
</li>
<li>
<p>Inputmask package name was changed from <code v-pre>jquery.inputmask</code> to <code v-pre>inputmask</code>. If you’ve configured path to<br>
assets manually, please adjust it.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-10" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-10"><span>Upgrade from Yii 2.0.10</span></a></h2>
<ul>
<li>
<p>A new method <code v-pre>public function emulateExecution($value = true);</code> has been added to the <code v-pre>yii\db\QueryInterace</code>.<br>
This method is implemented in the <code v-pre>yii\db\QueryTrait</code>, so this only affects your code if you implement QueryInterface<br>
in a class that does not use the trait.</p>
</li>
<li>
<p><code v-pre>yii\validators\FileValidator::getClientOptions()</code> and <code v-pre>yii\validators\ImageValidator::getClientOptions()</code> are now public.<br>
If you extend from these classes and override these methods, you must make them public as well.</p>
</li>
<li>
<p><code v-pre>yii\widgets\MaskedInput</code> inputmask dependency was updated to <code v-pre>~3.3.3</code>.<br>
<a href="https://github.com/RobinHerbots/Inputmask/blob/3.x/CHANGELOG.md" target="_blank" rel="noopener noreferrer">See its changelog for details</a>.</p>
</li>
<li>
<p>PJAX: Auto generated IDs of the Pjax widget have been changed to use their own prefix to avoid conflicts.<br>
Auto generated IDs are now prefixed with <code v-pre>p</code> instead of <code v-pre>w</code>. This is defined by the <code v-pre>$autoIdPrefix</code><br>
property of <code v-pre>yii\widgets\Pjax</code>. If you have any PHP or Javascript code that depends on autogenerated IDs<br>
you should update these to match this new value. It is not a good idea to rely on auto generated values anyway, so<br>
you better fix these cases by specifying an explicit ID.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-9" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-9"><span>Upgrade from Yii 2.0.9</span></a></h2>
<ul>
<li>
<p>RBAC: <code v-pre>getChildRoles()</code> method was added to <code v-pre>\yii\rbac\ManagerInterface</code>. If you’ve implemented your own RBAC manager<br>
you need to implement new method.</p>
</li>
<li>
<p>Microsoft SQL <code v-pre>NTEXT</code> data type <a href="https://msdn.microsoft.com/en-us/library/ms187993.aspx" target="_blank" rel="noopener noreferrer">was marked as deprecated</a> in MSSQL so<br>
<code v-pre>\yii\db\mssql\Schema::TYPE_TEXT</code> was changed from <code v-pre>'ntext'</code> to `’nvarchar(max)’</p>
</li>
<li>
<p>Method <code v-pre>yii\web\Request::getBodyParams()</code> has been changed to pass full value of ‘content-type’ header to the second<br>
argument of <code v-pre>yii\web\RequestParserInterface::parse()</code>. If you create your own custom parser, which relies on <code v-pre>$contentType</code><br>
argument, ensure to process it correctly as it may content additional data.</p>
</li>
<li>
<p><code v-pre>yii\rest\Serializer</code> has been changed to return a JSON array for collection data in all cases to be consistent among pages<br>
for data that is not indexed starting by 0. If your API relies on the Serializer to return data as JSON objects indexed by<br>
PHP array keys, you should set <code v-pre>yii\rest\Serializer::$preserveKeys</code> to <code v-pre>true</code>.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-8" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-8"><span>Upgrade from Yii 2.0.8</span></a></h2>
<ul>
<li>
<p>Part of code from <code v-pre>yii\web\User::loginByCookie()</code> method was moved to new <code v-pre>getIdentityAndDurationFromCookie()</code><br>
and <code v-pre>removeIdentityCookie()</code> methods. If you override <code v-pre>loginByCookie()</code> method, update it in order use new methods.</p>
</li>
<li>
<p>Fixture console command syntax was changed from <code v-pre>yii fixture &quot;*&quot; -User</code> to <code v-pre>yii fixture &quot;*, -User&quot;</code>. Upgrade your<br>
scripts if necessary.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-7" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-7"><span>Upgrade from Yii 2.0.7</span></a></h2>
<ul>
<li>
<p>The signature of <code v-pre>yii\helpers\BaseArrayHelper::index()</code> was changed. The method has got an extra optional parameter<br>
<code v-pre>$groups</code>.</p>
</li>
<li>
<p><code v-pre>yii\helpers\BaseArrayHelper</code> methods <code v-pre>isIn()</code> and <code v-pre>isSubset()</code> throw <code v-pre>\yii\base\InvalidParamException</code><br>
instead of <code v-pre>\InvalidArgumentException</code>. If you wrap calls of these methods in try/catch block, change expected<br>
exception class.</p>
</li>
<li>
<p><code v-pre>yii\rbac\ManagerInterface::canAddChild()</code> method was added. If you have custom backend for RBAC you need to implement<br>
it.</p>
</li>
<li>
<p>The signature of <code v-pre>yii\web\User::loginRequired()</code> was changed. The method has got an extra optional parameter<br>
<code v-pre>$checkAcceptHeader</code>.</p>
</li>
<li>
<p>The signature of <code v-pre>yii\db\ColumnSchemaBuilder::__construct()</code> was changed. The method has got an extra optional<br>
parameter <code v-pre>$db</code>. In case you are instantiating this class yourself and using the <code v-pre>$config</code> parameter, you will need to<br>
move it to the right by one.</p>
</li>
<li>
<p>String types in the MSSQL column schema map were upgraded to Unicode storage types. This will have no effect on<br>
existing columns, but any new columns you generate via the migrations engine will now store data as Unicode.</p>
</li>
<li>
<p>Output buffering was introduced in the pair of <code v-pre>yii\widgets\ActiveForm::init()</code> and <code v-pre>::run()</code>. If you override any of<br>
these methods, make sure that output buffer handling is not corrupted. If you call the parent implementation, when<br>
overriding, everything should work fine. You should be doing that anyway.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-6" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-6"><span>Upgrade from Yii 2.0.6</span></a></h2>
<ul>
<li>
<p>Added new requirement: ICU Data version &gt;= 49.1. Please, ensure that your environment has ICU data installed and<br>
up to date to prevent unexpected behavior or crashes. This may not be the case on older systems e.g. running Debian Wheezy.</p>
<blockquote>
<p>Tip: Use Yii 2 Requirements checker for easy and fast check. Look for <code v-pre>requirements.php</code> in root of Basic and Advanced<br>
templates (howto-comment is in head of the script).</p>
</blockquote>
</li>
<li>
<p>The signature of <code v-pre>yii\helpers\BaseInflector::transliterate()</code> was changed. The method is now public and has an<br>
extra optional parameter <code v-pre>$transliterator</code>.</p>
</li>
<li>
<p>In <code v-pre>yii\web\UrlRule</code> the <code v-pre>pattern</code> matching group names are being replaced with the placeholders on class<br>
initialization to support wider range of allowed characters. Because of this change:</p>
<ul>
<li>You are required to flush your application cache to remove outdated <code v-pre>UrlRule</code> serialized objects.<br>
See the <a href="http://www.yiiframework.com/doc-2.0/guide-caching-data.html#cache-flushing" target="_blank" rel="noopener noreferrer">Cache Flushing Guide</a></li>
<li>If you implement <code v-pre>parseRequest()</code> or <code v-pre>createUrl()</code> and rely on parameter names, call <code v-pre>substitutePlaceholderNames()</code><br>
in order to replace temporary IDs with parameter names after doing matching.</li>
</ul>
</li>
<li>
<p>The context of <code v-pre>yii.confirm</code> JavaScript function was changed from <code v-pre>yii</code> object to the DOM element which triggered<br>
the event.</p>
<ul>
<li>If you overrode the <code v-pre>yii.confirm</code> function and accessed the <code v-pre>yii</code> object through <code v-pre>this</code>, you must access it<br>
with global variable <code v-pre>yii</code> instead.</li>
</ul>
</li>
<li>
<p>Traversable objects are now formatted as arrays in XML response to support SPL objects and Generators. Previous<br>
behavior could be turned on by setting <code v-pre>XmlResponseFormatter::$useTraversableAsArray</code> to <code v-pre>false</code>.</p>
</li>
<li>
<p>If you’ve implemented <code v-pre>yii\rbac\ManagerInterface</code> you need to implement additional method <code v-pre>getUserIdsByRole($roleName)</code>.</p>
</li>
<li>
<p>If you’re using ApcCache with APCu, set <code v-pre>useApcu</code> to <code v-pre>true</code> in the component config.</p>
</li>
<li>
<p>The <code v-pre>yii\behaviors\SluggableBehavior</code> class has been refactored to make it more reusable.<br>
Added new <code v-pre>protected</code> methods:</p>
<ul>
<li><code v-pre>isSlugNeeded()</code></li>
<li><code v-pre>makeUnique()</code></li>
</ul>
<p>The visibility of the following Methods has changed from <code v-pre>private</code> to <code v-pre>protected</code>:</p>
<ul>
<li><code v-pre>validateSlug()</code></li>
<li><code v-pre>generateUniqueSlug()</code></li>
</ul>
</li>
<li>
<p>The <code v-pre>yii\console\controllers\MessageController</code> class has been refactored to be better configurable and now also allows<br>
setting a lot of configuration options via command line. If you extend from this class, make sure it works as expected after<br>
these changes.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-5" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-5"><span>Upgrade from Yii 2.0.5</span></a></h2>
<ul>
<li>The signature of the following methods in <code v-pre>yii\console\controllers\MessageController</code> has changed. They have an extra parameter <code v-pre>$markUnused</code>.
<ul>
<li><code v-pre>saveMessagesToDb($messages, $db, $sourceMessageTable, $messageTable, $removeUnused, $languages, $markUnused)</code></li>
<li><code v-pre>saveMessagesToPHP($messages, $dirName, $overwrite, $removeUnused, $sort, $markUnused)</code></li>
<li><code v-pre>saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused)</code></li>
<li><code v-pre>saveMessagesToPO($messages, $dirName, $overwrite, $removeUnused, $sort, $catalog, $markUnused)</code></li>
</ul>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-4" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-4"><span>Upgrade from Yii 2.0.4</span></a></h2>
<p>Upgrading from 2.0.4 to 2.0.5 does not require any changes.</p>
<h2 id="upgrade-from-yii-2-0-3" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-3"><span>Upgrade from Yii 2.0.3</span></a></h2>
<ul>
<li>
<p>Updated dependency to <code v-pre>cebe/markdown</code> to version <code v-pre>1.1.x</code>.<br>
If you need stick with 1.0.x, you can specify that in your <code v-pre>composer.json</code> by<br>
adding the following line in the <code v-pre>require</code> section:</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"cebe/markdown"</span><span class="token operator">:</span> <span class="token string">"~1.0.0"</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
</ul>
<h2 id="upgrade-from-yii-2-0-2" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-2"><span>Upgrade from Yii 2.0.2</span></a></h2>
<p>Starting from version 2.0.3 Yii <code v-pre>Security</code> component relies on OpenSSL crypto lib instead of Mcrypt. The reason is that<br>
Mcrypt is abandoned and isn’t maintained for years. Therefore your PHP should be compiled with OpenSSL support. Most<br>
probably there’s nothing to worry because it is quite typical.</p>
<p>If you’ve extended <code v-pre>yii\base\Security</code> to override any of the config constants you have to update your code:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`MCRYPT_CIPHER`</span> — now encoded in <span class="token string backtick-quoted-string">`$cipher`</span> <span class="token punctuation">(</span><span class="token keyword">and</span> hence <span class="token string backtick-quoted-string">`$allowedCiphers`</span><span class="token punctuation">)</span><span class="token operator">.</span></span>
<span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`MCRYPT_MODE`</span> — now encoded in <span class="token string backtick-quoted-string">`$cipher`</span> <span class="token punctuation">(</span><span class="token keyword">and</span> hence <span class="token string backtick-quoted-string">`$allowedCiphers`</span><span class="token punctuation">)</span><span class="token operator">.</span></span>
<span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`KEY_SIZE`</span> — now encoded in <span class="token string backtick-quoted-string">`$cipher`</span> <span class="token punctuation">(</span><span class="token keyword">and</span> hence <span class="token string backtick-quoted-string">`$allowedCiphers`</span><span class="token punctuation">)</span><span class="token operator">.</span></span>
<span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`KDF_HASH`</span> — now <span class="token string backtick-quoted-string">`$kdfHash`</span><span class="token operator">.</span></span>
<span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`MAC_HASH`</span> — now <span class="token string backtick-quoted-string">`$macHash`</span><span class="token operator">.</span></span>
<span class="line"><span class="token operator">-</span> <span class="token string backtick-quoted-string">`AUTH_KEY_INFO`</span> — now <span class="token string backtick-quoted-string">`$authKeyInfo`</span><span class="token operator">.</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="upgrade-from-yii-2-0-0" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-0"><span>Upgrade from Yii 2.0.0</span></a></h2>
<ul>
<li>
<p>Upgraded Twitter Bootstrap to <a href="http://blog.getbootstrap.com/2014/10/29/bootstrap-3-3-0-released/" target="_blank" rel="noopener noreferrer">version 3.3.x</a>.<br>
If you need to use an older version (i.e. stick with 3.2.x) you can specify that in your <code v-pre>composer.json</code> by<br>
adding the following line in the <code v-pre>require</code> section:</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"bower-asset/bootstrap"</span><span class="token operator">:</span> <span class="token string">"3.2.*"</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
</ul>
<h2 id="upgrade-from-yii-2-0-rc" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-rc"><span>Upgrade from Yii 2.0 RC</span></a></h2>
<ul>
<li>
<p>If you’ve implemented <code v-pre>yii\rbac\ManagerInterface</code> you need to add implementation for new method <code v-pre>removeChildren()</code>.</p>
</li>
<li>
<p>The input dates for datetime formatting are now assumed to be in UTC unless a timezone is explicitly given.<br>
Before, the timezone assumed for input dates was the default timezone set by PHP which is the same as <code v-pre>Yii::$app-&gt;timeZone</code>.<br>
This causes trouble because the formatter uses <code v-pre>Yii::$app-&gt;timeZone</code> as the default values for output so no timezone conversion<br>
was possible. If your timestamps are stored in the database without a timezone identifier you have to ensure they are in UTC or<br>
add a timezone identifier explicitly.</p>
</li>
<li>
<p><code v-pre>yii\bootstrap\Collapse</code> is now encoding labels by default. <code v-pre>encode</code> item option and global <code v-pre>encodeLabels</code> property were<br>
introduced to disable it. Keys are no longer used as labels. You need to remove keys and use <code v-pre>label</code> item option instead.</p>
</li>
<li>
<p>The <code v-pre>yii\base\View::beforeRender()</code> and <code v-pre>yii\base\View::afterRender()</code> methods have two extra parameters <code v-pre>$viewFile</code><br>
and <code v-pre>$params</code>. If you are overriding these methods, you should adjust the method signature accordingly.</p>
</li>
<li>
<p>If you’ve used <code v-pre>asImage</code> formatter i.e. <code v-pre>Yii::$app-&gt;formatter-&gt;asImage($value, $alt);</code> you should change it<br>
to <code v-pre>Yii::$app-&gt;formatter-&gt;asImage($value, ['alt' =&gt; $alt]);</code>.</p>
</li>
<li>
<p>Yii now requires <code v-pre>cebe/markdown</code> 1.0.0 or higher, which includes breaking changes in its internal API. If you extend the markdown class<br>
you need to update your implementation. See <a href="https://github.com/cebe/markdown/releases/tag/1.0.0-rc" target="_blank" rel="noopener noreferrer">github.com/cebe/markdown/releases/...</a> for details.<br>
If you just used the markdown helper class there is no need to change anything.</p>
</li>
<li>
<p>If you are using CUBRID DBMS, make sure to use at least version 9.3.0 as the server and also as the PDO extension.<br>
Quoting of values is broken in prior versions and Yii has no reliable way to work around this issue.<br>
A workaround that may have worked before has been removed in this release because it was not reliable.</p>
</li>
</ul>
<h2 id="upgrade-from-yii-2-0-beta" tabindex="-1"><a class="header-anchor" href="#upgrade-from-yii-2-0-beta"><span>Upgrade from Yii 2.0 Beta</span></a></h2>
<ul>
<li>
<p>If you are using Composer to upgrade Yii, you should run the following command first (once for all) to install<br>
the composer-asset-plugin, <em>before</em> you update your project:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php composer<span class="token operator">.</span>phar <span class="token keyword">global</span> <span class="token keyword">require</span> <span class="token string double-quoted-string">"fxp/composer-asset-plugin:~1.3.1"</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>You also need to add the following code to your project’s <code v-pre>composer.json</code> file:</p>
<div class="language-json line-numbers-mode" data-highlighter="prismjs" data-ext="json" data-title="json"><pre v-pre class="language-json"><code><span class="line"><span class="token property">"extra"</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token property">"asset-installer-paths"</span><span class="token operator">:</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token property">"npm-asset-library"</span><span class="token operator">:</span> <span class="token string">"vendor/npm"</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token property">"bower-asset-library"</span><span class="token operator">:</span> <span class="token string">"vendor/bower"</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>It is also a good idea to upgrade composer itself to the latest version if you see any problems:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">composer <span class="token keyword">self</span><span class="token operator">-</span>update</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
<li>
<p>If you used <code v-pre>clearAll()</code> or <code v-pre>clearAllAssignments()</code> of <code v-pre>yii\rbac\DbManager</code>, you should replace<br>
them with <code v-pre>removeAll()</code> and <code v-pre>removeAllAssignments()</code> respectively.</p>
</li>
<li>
<p>If you created RBAC rule classes, you should modify their <code v-pre>execute()</code> method by adding <code v-pre>$user</code><br>
as the first parameter: <code v-pre>execute($user, $item, $params)</code>. The <code v-pre>$user</code> parameter represents<br>
the ID of the user currently being access checked. Previously, this is passed via <code v-pre>$params['user']</code>.</p>
</li>
<li>
<p>If you override <code v-pre>yii\grid\DataColumn::getDataCellValue()</code> with visibility <code v-pre>protected</code> you have<br>
to change visibility to <code v-pre>public</code> as visibility of the base method has changed.</p>
</li>
<li>
<p>If you have classes implementing <code v-pre>yii\web\IdentityInterface</code> (very common), you should modify<br>
the signature of <code v-pre>findIdentityByAccessToken()</code> as<br>
<code v-pre>public static function findIdentityByAccessToken($token, $type = null)</code>. The new <code v-pre>$type</code> parameter<br>
will contain the type information about the access token. For example, if you use<br>
<code v-pre>yii\filters\auth\HttpBearerAuth</code> authentication method, the value of this parameter will be<br>
<code v-pre>yii\filters\auth\HttpBearerAuth</code>. This allows you to differentiate access tokens taken by<br>
different authentication methods.</p>
</li>
<li>
<p>If you are sharing the same cache across different applications, you should configure<br>
the <code v-pre>keyPrefix</code> property of the cache component to use some unique string.<br>
Previously, this property was automatically assigned with a unique string.</p>
</li>
<li>
<p>If you are using <code v-pre>dropDownList()</code>, <code v-pre>listBox()</code>, <code v-pre>activeDropDownList()</code>, or <code v-pre>activeListBox()</code><br>
of <code v-pre>yii\helpers\Html</code>, and your list options use multiple blank spaces to format and align<br>
option label texts, you need to specify the option <code v-pre>encodeSpaces</code> to be true.</p>
</li>
<li>
<p>If you are using <code v-pre>yii\grid\GridView</code> and have configured a data column to use a PHP callable<br>
to return cell values (via <code v-pre>yii\grid\DataColumn::value</code>), you may need to adjust the signature<br>
of the callable to be <code v-pre>function ($model, $key, $index, $widget)</code>. The <code v-pre>$key</code> parameter was newly added<br>
in this release.</p>
</li>
<li>
<p><code v-pre>yii\console\controllers\AssetController</code> is now using hashes instead of timestamps. Replace all <code v-pre>{ts}</code> with <code v-pre>{hash}</code>.</p>
</li>
<li>
<p>The database table of the <code v-pre>yii\log\DbTarget</code> now needs a <code v-pre>prefix</code> column to store context information.<br>
You can add it with <code v-pre>ALTER TABLE log ADD COLUMN prefix TEXT AFTER log_time;</code>.</p>
</li>
<li>
<p>The <code v-pre>fileinfo</code> PHP extension is now required by Yii. If you use <code v-pre>yii\helpers\FileHelper::getMimeType()</code>, make sure<br>
you have enabled this extension. This extension is <a href="https://www.php.net/manual/en/fileinfo.installation.php" target="_blank" rel="noopener noreferrer">builtin</a> in php above <code v-pre>5.3</code>.</p>
</li>
<li>
<p>Please update your main layout file by adding this line in the <code v-pre>&lt;head&gt;</code> section: <code v-pre>&lt;?= Html::csrfMetaTags() ?&gt;</code>.<br>
This change is needed because <code v-pre>yii\web\View</code> no longer automatically generates CSRF meta tags due to issue #3358.</p>
</li>
<li>
<p>If your model code is using the <code v-pre>file</code> validation rule, you should rename its <code v-pre>types</code> option to <code v-pre>extensions</code>.</p>
</li>
<li>
<p><code v-pre>MailEvent</code> class has been moved to the <code v-pre>yii\mail</code> namespace. You have to adjust all references that may exist in your code.</p>
</li>
<li>
<p>The behavior and signature of <code v-pre>ActiveRecord::afterSave()</code> has changed. <code v-pre>ActiveRecord::$isNewRecord</code> will now always be<br>
false in afterSave and also dirty attributes are not available. This change has been made to have a more consistent and<br>
expected behavior. The changed attributes are now available in the new parameter of afterSave() <code v-pre>$changedAttributes</code>.<br>
<code v-pre>$changedAttributes</code> contains the old values of attributes that had changed and were saved.</p>
</li>
<li>
<p><code v-pre>ActiveRecord::updateAttributes()</code> has been changed to not trigger events and not respect optimistic locking anymore to<br>
differentiate it more from calling <code v-pre>update(false)</code> and to ensure it can be used in <code v-pre>afterSave()</code> without triggering infinite<br>
loops.</p>
</li>
<li>
<p>If you are developing RESTful APIs and using an authentication method such as <code v-pre>yii\filters\auth\HttpBasicAuth</code>,<br>
you should explicitly configure <code v-pre>yii\web\User::enableSession</code> in the application configuration to be false to avoid<br>
starting a session when authentication is performed. Previously this was done automatically by authentication method.</p>
</li>
<li>
<p><code v-pre>mail</code> component was renamed to <code v-pre>mailer</code>, <code v-pre>yii\log\EmailTarget::$mail</code> was renamed to <code v-pre>yii\log\EmailTarget::$mailer</code>.<br>
Please update all references in the code and config files.</p>
</li>
<li>
<p><code v-pre>yii\caching\GroupDependency</code> was renamed to <code v-pre>TagDependency</code>. You should create such a dependency using the code<br>
<code v-pre>new \yii\caching\TagDependency(['tags' =&gt; 'TagName'])</code>, where <code v-pre>TagName</code> is similar to the group name that you<br>
previously used.</p>
</li>
<li>
<p>If you are using the constant <code v-pre>YII_PATH</code> in your code, you should rename it to <code v-pre>YII2_PATH</code> now.</p>
</li>
<li>
<p>You must explicitly configure <code v-pre>yii\web\Request::cookieValidationKey</code> with a secret key. Previously this is done automatically.<br>
To do so, modify your application configuration like the following:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line">    <span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'request'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'cookieValidationKey'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'your secret key here'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Note: If you are using the <code v-pre>Advanced Project Template</code> you should not add this configuration to <code v-pre>common/config</code><br>
or <code v-pre>console/config</code> because the console application doesn’t have to deal with CSRF and uses its own request that<br>
doesn’t have <code v-pre>cookieValidationKey</code> property.</p>
</blockquote>
</li>
<li>
<p><code v-pre>yii\rbac\PhpManager</code> now stores data in three separate files instead of one. In order to convert old file to<br>
new ones save the following code as <code v-pre>convert.php</code> that should be placed in the same directory your <code v-pre>rbac.php</code> is in:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"><span class="token variable">$oldFile</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'rbac.php'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$itemsFile</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'items.php'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$assignmentsFile</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'assignments.php'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$rulesFile</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'rules.php'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$oldData</span> <span class="token operator">=</span> <span class="token keyword">include</span> <span class="token variable">$oldFile</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">function</span> <span class="token function-definition function">saveToFile</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">,</span> <span class="token variable">$fileName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$out</span> <span class="token operator">=</span> <span class="token function">var_export</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$out</span> <span class="token operator">=</span> <span class="token string double-quoted-string">"&lt;?php\nreturn "</span> <span class="token operator">.</span> <span class="token variable">$out</span> <span class="token operator">.</span> <span class="token string single-quoted-string">';'</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$out</span> <span class="token operator">=</span> <span class="token function">str_replace</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'array ('</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">')'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'['</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">']'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$out</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token function">file_put_contents</span><span class="token punctuation">(</span><span class="token variable">$fileName</span><span class="token punctuation">,</span> <span class="token variable">$out</span><span class="token punctuation">,</span> <span class="token constant">LOCK_EX</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$items</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$assignments</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$oldData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'items'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$oldData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'items'</span><span class="token punctuation">]</span> <span class="token keyword">as</span> <span class="token variable">$name</span> <span class="token operator">=></span> <span class="token variable">$data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'assignments'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'assignments'</span><span class="token punctuation">]</span> <span class="token keyword">as</span> <span class="token variable">$userId</span> <span class="token operator">=></span> <span class="token variable">$assignmentData</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                <span class="token variable">$assignments</span><span class="token punctuation">[</span><span class="token variable">$userId</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$assignmentData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'roleName'</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">            <span class="token punctuation">}</span></span>
<span class="line">            <span class="token keyword">unset</span><span class="token punctuation">(</span><span class="token variable">$data</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'assignments'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">        <span class="token variable">$items</span><span class="token punctuation">[</span><span class="token variable">$name</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$data</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$rules</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">isset</span><span class="token punctuation">(</span><span class="token variable">$oldData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'rules'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$rules</span> <span class="token operator">=</span> <span class="token variable">$oldData</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'rules'</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token function">saveToFile</span><span class="token punctuation">(</span><span class="token variable">$items</span><span class="token punctuation">,</span> <span class="token variable">$itemsFile</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token function">saveToFile</span><span class="token punctuation">(</span><span class="token variable">$assignments</span><span class="token punctuation">,</span> <span class="token variable">$assignmentsFile</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token function">saveToFile</span><span class="token punctuation">(</span><span class="token variable">$rules</span><span class="token punctuation">,</span> <span class="token variable">$rulesFile</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">echo</span> <span class="token string double-quoted-string">"Done!\n"</span><span class="token punctuation">;</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Run it once, delete <code v-pre>rbac.php</code>. If you’ve configured <code v-pre>authFile</code> property, remove the line from config and instead<br>
configure <code v-pre>itemFile</code>, <code v-pre>assignmentFile</code> and <code v-pre>ruleFile</code>.</p>
</li>
<li>
<p>Static helper <code v-pre>yii\helpers\Security</code> has been converted into an application component. You should change all usage of<br>
its methods to a new syntax, for example: instead of <code v-pre>yii\helpers\Security::hashData()</code> use <code v-pre>Yii::$app-&gt;getSecurity()-&gt;hashData()</code>.<br>
The <code v-pre>generateRandomKey()</code> method now produces not an ASCII compatible output. Use <code v-pre>generateRandomString()</code> instead.<br>
Default encryption and hash parameters has been upgraded. If you need to decrypt/validate data that was encrypted/hashed<br>
before, use the following configuration of the ‘security’ component:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'components'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'security'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'derivationIterations'</span> <span class="token operator">=></span> <span class="token number">1000</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>If you are using query caching, you should modify your relevant code as follows, as <code v-pre>beginCache()</code> and <code v-pre>endCache()</code> are<br>
replaced by <code v-pre>cache()</code>:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$db</span><span class="token operator">-></span><span class="token function">cache</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$db</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line"></span>
<span class="line">   <span class="token comment">// ... SQL queries that need to use query caching</span></span>
<span class="line"></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token variable">$duration</span><span class="token punctuation">,</span> <span class="token variable">$dependency</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>Due to significant changes to security you need to upgrade your code to use <code v-pre>\yii\base\Security</code> component instead of<br>
helper. If you have any data encrypted it should be re-encrypted. In order to do so you can use old security helper<br>
<a href="https://github.com/yiisoft/yii2/issues/4461#issuecomment-50237807" target="_blank" rel="noopener noreferrer">as explained by @docsolver at github</a>.</p>
</li>
<li>
<p>[[yii\helpers\Url::to()]] will no longer prefix base URL to relative URLs. For example, <code v-pre>Url::to('images/logo.png')</code><br>
will return <code v-pre>images/logo.png</code> directly. If you want a relative URL to be prefix with base URL, you should make use<br>
of the alias <code v-pre>@web</code>. For example, <code v-pre>Url::to('@web/images/logo.png')</code> will return <code v-pre>/BaseUrl/images/logo.png</code>.</p>
</li>
<li>
<p>The following properties are now taking <code v-pre>false</code> instead of <code v-pre>null</code> for “don’t use” case:</p>
<ul>
<li><code v-pre>yii\bootstrap\NavBar::$brandLabel</code>.</li>
<li><code v-pre>yii\bootstrap\NavBar::$brandUrl</code>.</li>
<li><code v-pre>yii\bootstrap\Modal::$closeButton</code>.</li>
<li><code v-pre>yii\bootstrap\Modal::$toggleButton</code>.</li>
<li><code v-pre>yii\bootstrap\Alert::$closeButton</code>.</li>
<li><code v-pre>yii\widgets\LinkPager::$nextPageLabel</code>.</li>
<li><code v-pre>yii\widgets\LinkPager::$prevPageLabel</code>.</li>
<li><code v-pre>yii\widgets\LinkPager::$firstPageLabel</code>.</li>
<li><code v-pre>yii\widgets\LinkPager::$lastPageLabel</code>.</li>
</ul>
</li>
<li>
<p>The format of the Faker fixture template is changed. For an example, please refer to the file<br>
<code v-pre>apps/advanced/common/tests/templates/fixtures/user.php</code>.</p>
</li>
<li>
<p>The signature of all file downloading methods in <code v-pre>yii\web\Response</code> is changed, as summarized below:</p>
<ul>
<li><code v-pre>sendFile($filePath, $attachmentName = null, $options = [])</code></li>
<li><code v-pre>sendContentAsFile($content, $attachmentName, $options = [])</code></li>
<li><code v-pre>sendStreamAsFile($handle, $attachmentName, $options = [])</code></li>
<li><code v-pre>xSendFile($filePath, $attachmentName = null, $options = [])</code></li>
</ul>
</li>
<li>
<p>The signature of callbacks used in <code v-pre>yii\base\ArrayableTrait::fields()</code> is changed from <code v-pre>function ($field, $model) {</code><br>
to <code v-pre>function ($model, $field) {</code>.</p>
</li>
<li>
<p><code v-pre>Html::radio()</code>, <code v-pre>Html::checkbox()</code>, <code v-pre>Html::radioList()</code>, <code v-pre>Html::checkboxList()</code> no longer generate the container<br>
tag around each radio/checkbox when you specify labels for them. You should manually render such container tags,<br>
or set the <code v-pre>item</code> option for <code v-pre>Html::radioList()</code>, <code v-pre>Html::checkboxList()</code> to generate the container tags.</p>
</li>
<li>
<p>The formatter class has been refactored to have only one class regardless whether PHP intl extension is installed or not.<br>
Functionality of <code v-pre>yii\base\Formatter</code> has been merged into <code v-pre>yii\i18n\Formatter</code> and <code v-pre>yii\base\Formatter</code> has been<br>
removed so you have to replace all usage of <code v-pre>yii\base\Formatter</code> with <code v-pre>yii\i18n\Formatter</code> in your code.<br>
Also the API of the Formatter class has changed in many ways.<br>
The signature of the following Methods has changed:</p>
<ul>
<li><code v-pre>asDate</code></li>
<li><code v-pre>asTime</code></li>
<li><code v-pre>asDatetime</code></li>
<li><code v-pre>asSize</code> has been split up into <code v-pre>asSize</code> and <code v-pre>asShortSize</code></li>
<li><code v-pre>asCurrency</code></li>
<li><code v-pre>asDecimal</code></li>
<li><code v-pre>asPercent</code></li>
<li><code v-pre>asScientific</code></li>
</ul>
<p>The following methods have been removed, this also means that the corresponding format which may be used by a<br>
GridView or DetailView is not available anymore:</p>
<ul>
<li><code v-pre>asNumber</code></li>
<li><code v-pre>asDouble</code></li>
</ul>
<p>Also due to these changes some formatting defaults have changes so you have to check all your GridView and DetailView<br>
configuration and make sure the formatting is displayed correctly.</p>
<p>The configuration for <code v-pre>asSize()</code> has changed. It now uses the configuration for the number formatting from intl<br>
and only the base is configured using <code v-pre>$sizeFormatBase</code>.</p>
<p>The specification of the date and time formats is now using the ICU pattern format even if PHP intl extension is not installed.<br>
You can prefix a date format with <code v-pre>php:</code> to use the old format of the PHP <code v-pre>date()</code>-function.</p>
</li>
<li>
<p>The DateValidator has been refactored to use the same format as the Formatter class now (see previous change).<br>
When you use the DateValidator and did not specify a format it will now be what is configured in the formatter class instead of ‘Y-m-d’.<br>
To get the old behavior of the DateValidator you have to set the format explicitly in your validation rule:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span><span class="token string single-quoted-string">'attributeName'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'format'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'php:Y-m-d'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div></li>
<li>
<p><code v-pre>beforeValidate()</code>, <code v-pre>beforeValidateAll()</code>, <code v-pre>afterValidate()</code>, <code v-pre>afterValidateAll()</code>, <code v-pre>ajaxBeforeSend()</code> and <code v-pre>ajaxComplete()</code><br>
are removed from <code v-pre>ActiveForm</code>. The same functionality is now achieved via JavaScript event mechanism like the following:</p>
<div class="language-javascript line-numbers-mode" data-highlighter="prismjs" data-ext="js" data-title="js"><pre v-pre class="language-javascript"><code><span class="line"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#myform'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'beforeValidate'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> messages<span class="token punctuation">,</span> deferreds</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// called when the validation is triggered by submitting the form</span></span>
<span class="line">    <span class="token comment">// return false if you want to cancel the validation for the whole form</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'beforeValidateAttribute'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> attribute<span class="token punctuation">,</span> messages<span class="token punctuation">,</span> deferreds</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// before validating an attribute</span></span>
<span class="line">    <span class="token comment">// return false if you want to cancel the validation for the attribute</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'afterValidateAttribute'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> attribute<span class="token punctuation">,</span> messages</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'afterValidate'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> messages</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'beforeSubmit'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// after all validations have passed</span></span>
<span class="line">    <span class="token comment">// you can do ajax form submission here</span></span>
<span class="line">    <span class="token comment">// return false if you want to stop form submission</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
<li>
<p>The signature of <code v-pre>View::registerJsFile()</code> and <code v-pre>View::registerCssFile()</code> has changed. The <code v-pre>$depends</code> and <code v-pre>$position</code><br>
paramaters have been merged into <code v-pre>$options</code>. The new signatures are as follows:</p>
<ul>
<li><code v-pre>registerJsFile($url, $options = [], $key = null)</code></li>
<li><code v-pre>registerCssFile($url, $options = [], $key = null)</code></li>
</ul>
</li>
</ul>
<blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


